/*
		ServEngine framework library
		A library to fast develop JEE online applications
	
		Copyright 2008 José Ignacio de Córdoba Álvaro

		Licensed under the Apache License, Version 2.0 (the "License");
		you may not use this file except in compliance with the License.
		You may obtain a copy of the License at

				http://www.apache.org/licenses/LICENSE-2.0

		Unless required by applicable law or agreed to in writing, software
		distributed under the License is distributed on an "AS IS" BASIS,
		WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
		See the License for the specific language governing permissions and
		limitations under the License.
	
		Jose Ignacio de Cordoba Alvaro
		http://ignacio.decordoba.com
*/

package com.servengine.user;

import com.servengine.image.ThumbnailUtils;
import com.servengine.portal.Portal;
import com.servengine.struts.AuthorizeAction;
import com.servengine.struts.ClientAction;
import com.servengine.struts.UnidentifiedUserAction;

import java.awt.Dimension;
import java.awt.Image;
import java.awt.image.BufferedImage;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

import java.net.URL;

import java.rmi.RemoteException;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import java.util.Random;

import javax.ejb.FinderException;

import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;

import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import javax.transaction.UserTransaction;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

/**
 * this class name is not UnidentifiedUserActions because: User is the name of the object related to this Unidentified"User"Actions.
 * The real name for these classes could be XUnidentifiedUserActions (UserUnidentifiedUserActions in this case) but would make very long classnames.
 */
public class UserUnidentifiedActions extends ClientAction implements UnidentifiedUserAction
{
	private static org.apache.commons.logging.Log log = org.apache.commons.logging.LogFactory.getLog( UserUnidentifiedActions.class.getName() );
	Map<Integer,byte[]> thumbnails;
	
//	MailRelayLocal mailRelay;
	public void initAction(javax.naming.Context context)
	{
	  /*try
	  {
	    mailRelay = (MailRelayLocal) initialcontext.lookup("MailRelay/local");
	  } catch (Exception e)
	  {
	    log.error(e.getMessage(), e);
	    throw new IllegalStateException(e.getMessage());
	  }*/
		log.info(getClass().getName()+" initialized");
	}


	/**
	 * @deprecated Please use signup method
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 * @throws ServletException
	 */
	public ActionForward create(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		return signup(mapping,form,request,response);
	}
	public ActionForward signup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
	  UserTransaction ut = null;
		try
		{
		  ut = getUserTransaction();
			UserSessionSBean userSession = getUserSession(request);
		  UserActionForm user = (UserActionForm)form;
			if (usermanager.exists(userSession.getPortalid(),user.getUserid()))
				throw new IllegalArgumentException("error.userExists");
		  if (user.getNewpassword()==null || user.getNewpassword().equals(""))
		    throw new IllegalArgumentException("error.passwordIsRequired");
		  if (!user.getNewpassword().equals(user.getNewpassword2()))
		    throw new IllegalArgumentException("error.passwordsMustBeTheSame");
			if (userSession.getPortal().isRequiresSignupConfirmation() && (user.getEmail()==null || user.getEmail().indexOf("@")==-1))
				throw new IllegalArgumentException("error.emailIsRequired");
			Portal portal = portalmanager.getPortal(user.getPortalid());
			for (ExtraUserdataField field: portal.getExtraUserdataFields())
				if (field.isRequired() && (user.getExtraUserdataMap().get(field.getName())==null || user.getExtraUserdataMap().get(field.getName()).equals("")))
					throw new IllegalArgumentException("error.missingRequiredField");
			User userDTO = new User(userSession.getPortal(),user.getUserid());
			PropertyUtils.copyProperties(userDTO,user);
			user.setId(null);//Por seguridad
			usermanager.persist(userDTO, user.getExtraUserdataMap());
//			User userdto = new User(portal,user.getUserid());
//			PropertyUtils.copyProperties(userdto,user);
		  userDTO.encodePassword(user.getNewpassword());
			userDTO.setRoles(usermanager.getNewUserRoles(portal.getId()));
			usermanager.persist(userDTO,null);
			userSession = getServletContextUtils().getUserSessionSBean(usermanager.getUserSession(userSession.getPortalid(),user.getUserid(),user.getNewpassword()));
		  request.getSession().setAttribute(AuthorizeAction.USERSESSIONSBEAN_ATTRIBUTEID,userSession);
		  doLoginCookies(userSession,0,response);
		  if (user.getPictureFile()!=null && user.getPictureFile().getFileSize()>0)
		  {
		    Image picture = ThumbnailUtils.JPEGtoImage(user.getPictureFile().getInputStream());
		    if (picture.getWidth(null)>320 || picture.getHeight(null)>240) //TODO poner esto como parámetro de aplicación
		    {
		      BufferedImage bufferedImage = ThumbnailUtils.getScaledimage(picture,new Dimension(320,240));
		      ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
		      ThumbnailUtils.writeJPG(bufferedImage,byteOutputStream,(float)0.5);
		      userDTO.setPicture(byteOutputStream.toByteArray());
		      //ThumbnailUtils.writeJPG(bufferedImage,new java.io.File(getServicedir(user.getPortalid(),"user",true),user.getPkey()+".jpg"),(float)0.5);
		    } else
		      //new com.servengine.util.File(getServicedir(user.getPortalid(),"user",true),user.getPkey()+".jpg").store(userForm.getPicture().getInputStream());
		      userDTO.setPicture(user.getPictureFile().getFileData());
		    //user.setHasPicture(true);
		  } /*else
		    user.setHasPicture(new java.io.File(getServicedir(user.getPortalid(),"user",true),user.getPkey()+".jpg").exists());*/

		  if (userSession.getPortal().isRequiresSignupConfirmation())
		    //try //Si hay algún error, el proceso de alta se aborta y se llega al rollback.
		    {
		      request.setAttribute("authCode",getSignupsignature(user.getPortalid(), user.getUserid()));
		      String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/signupConfirmationRequestMail.jsp");
		      getMailRelay().send(portalmanager.getEmail(userSession.getPortalid()).getAddress(), userDTO.getEmail(), "Signup confirmation request", null, html);
		    } /*catch (MessagingException e)
		    {
		      log.error(e.getMessage(), e);
		    }*/
		  else
				try
				{
					InternetAddress portalEmail = portalmanager.getEmail(userSession.getPortalid());
					if (portalEmail!=null)
					{
						String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/welcomeMail.jsp");
						getMailRelay().send(portalEmail.getAddress(), userDTO.getEmail(), "Signup confirmation", null, html);
						if (userSession.getPortal().isUserSelfSignup())
						{
							html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/admin/newUserNotificationMail.jsp");
							getMailRelay().send(portalEmail.getAddress(), portalEmail.getAddress(), "Signup confirmation", null, html);
						}
					}
				} catch (Throwable e)
				{
					log.error(e.getMessage(),e);
					log.warn("User signup succeded as previous error was related to wellcome and notification mails.");
				}
			logManager.log(user.getPortalid(),user.getId(),"user","UserUnidentifiedActions","signup",user.getUserid(),request.getRemoteAddr());
			ut.commit();
		  if (portal.isRequiresSignupConfirmation())
		    return mapping.findForward("signupConfirmationRequestMailSent");
		  return mapping.findForward("signup");
		} catch (Throwable e)
		{
		  try
		  {
		    ut.rollback();
		  } catch (Exception e2)
		  {
		    log.error(e.getMessage(),e2);
		  }
			log.error(e.getMessage(),e);
			saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
/*	public void sendSignupconfirmationrequestmail(User user) throws MessagingException, FinderException
		{
			Map substitutions = new HashMap();
			substitutions.put("${userid}", user.getUserid());
			substitutions.put("${homeurl}", user.getPortal().getHomeurl());
			substitutions.put("${authCode}", getSignupsignature(user.getPortalid(), user.getUserid()));
			InternetAddress adminemail = user.getPortal().getEmail();
			if (adminemail==null)
				throw new IllegalStateException("error.noAdminEmail");
			mailrelay.send(user.getPortalid(), adminemail.toString(), user.getEmail(),
					"user.signupConfirmationRequest", substitutions,null);
		}*/
	/**
	 * @deprecated Please use signupForm
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 * @throws ServletException
	 */
	public ActionForward signupform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
	  return mapping.findForward("signupform");
	}
	public ActionForward signupForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
	  try
	  {
	    UserSessionSBean userSession = getUserSession(request);
			if (!userSession.isGuest())
				return logout(mapping,form,request,response); //Si se quiere dar de alta, le hacemos logout antes.
			if (!userSession.getPortal().isUserSelfSignup())
				throw new IllegalArgumentException("portal.userSelfSignupDisabled");
	    logManager.log(userSession.getPortalid(),userSession.getUser().getId(),"user","UserUnidentifiedActions","signupForm","",request.getRemoteAddr());
	    UserActionForm user = (UserActionForm)form;
			for (ExtraUserdataField field: userSession.getPortal().getExtraUserdataFields())
				if (field.getDefaultValue()!=null && field.getDefaultValue().length()>0)
					user.setExtradatum(field.getName(),field.getDefaultValue());
			return mapping.findForward("signupForm");
	  } catch (Throwable e)
	  {
	    log.error(e.getMessage(),e);
	    saveErrors(request,getErrorsFromException(e));
	    return mapping.findForward("error");
	  }
	}
	public ActionForward confirmSignup(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		try
		{
		  UserActionForm user = (UserActionForm)form;
			usermanager.signupConfirmation(usermanager.getUser(user.getPortalid(),user.getUserid()),request.getParameter("authCode"));
		  logManager.log(user.getPortalid(),null,"user","UserUnidentifiedActions","confirmSignup",user.getUserid(),request.getRemoteAddr());
		  return mapping.findForward("confirmSignup");
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
		  saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	
	public ActionForward loginForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
//		HttpSession session = request.getSession();
//		if (session.getAttribute("requestURI")!=null)
//		{
//							request.setAttribute("forward",URLEncoder.encode((String)session.getAttribute("requestURI"),"UTF-8"));
//		  request.setAttribute("forward",session.getAttribute("requestURI"));
//			session.removeAttribute("requestURI");
//		}
	  UserActionForm user = (UserActionForm)form;
		user.setPortalid(getUserSession(request).getPortalid());
		return mapping.findForward("loginform");
	}

	/**
	 * @deprecated Please use loginForm()
	 * @param mapping
	 * @param form
	 * @param request
	 * @param response
	 * @return
	 * @throws IOException
	 * @throws ServletException
	 */
	public ActionForward loginform(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		return loginForm(mapping,form,request,response);
	}

	/**
	 * this method is here to group login process and to be invoked from anywhere in the code, if necesary. Ex: MondoDemo login process
	 * UserSBean must be get from UserManager (if not, it will not have UserSession)
	 */
	public static void doLoginCookies(UserSessionSBean userSession, int autoLoginDays, HttpServletResponse response) throws Exception
	{
	  try
	  {
	    Cookie cookie = new Cookie("portalid",userSession.getPortalid());
	    cookie.setMaxAge(7*60*60*24); // Siete d%%as.
	    cookie.setPath("/");
	    response.addCookie(cookie);
	    if (autoLoginDays>0)
	    {
	      cookie = new Cookie("servengineautologin#"+userSession.getPortalid(),userSession.getId()+","+userSession.getUserSession().getEncodedId());
	      cookie.setMaxAge(autoLoginDays*60*60*24);
	      cookie.setPath("/");
	      response.addCookie(cookie);
	      if (log.isDebugEnabled()) log.debug(cookie.getName()+"="+cookie.getValue());
	    }
	  } catch (Throwable e)
	  {
	    log.error(e.getMessage(),e);
	    throw new javax.security.auth.login.FailedLoginException(e+": "+e.getMessage());
	  }
	}

	protected void removeRememberedSession(String portalid, HttpServletResponse response) throws IOException,ServletException
	{
		javax.servlet.http.Cookie cookie = new javax.servlet.http.Cookie("servengineautologin#"+portalid,"");
		cookie.setMaxAge(0);
		cookie.setPath("/");
		response.addCookie(cookie);
	}

	public ActionForward login(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
//		response.addHeader("P3P","CP=\"CAO PSA OUR\"");
		UserActionForm user = (UserActionForm)form;
		if (user.getPortalid()==null)
			user.setPortalid(getPortalidfromcookies(request));
		try
		{
			UserSessionSBean userSession = getServletContextUtils().getUserSessionSBean(usermanager.getUserSession(user.getPortalid(),user.getUserid(),user.getPassword()));
		  request.getSession().setAttribute(AuthorizeAction.USERSESSIONSBEAN_ATTRIBUTEID,userSession);
			setLocale(request,userSession.getLocale());
			doLoginCookies(userSession,user.isRemembersession()?userSession.getPortal().getSessionRememberDays():0,response);
//			userSession.getUser().setHasPicture(new java.io.File(getServicedir(userSession.getPortalid(),"user",true),userSession.getUser().getPkey()+".jpg").exists());
		  Map<String,String> warnings = new HashMap<String,String>();
			if (user.isRemembersession()&&userSession.getPortal().getSessionRememberDays()==0)
		    warnings.put("autoSignInIsDisabled","user");
		  if (userSession.isAdmin())
				warnings.putAll(getPortalWarnings(getUserSession(request).getPortal()));
			request.setAttribute("warnings", warnings);
			log.info("login: "+user.getUserid()+"@"+user.getPortalid()+" ("+userSession.getUser().getName()+")");
		  logManager.log(user.getPortalid(),userSession.getUser().getId(),"user","UserUnidentifiedActions","login",user.getUserid(),request.getRemoteAddr());
			if (request.getParameter("forward")!=null && request.getParameter("forward").length()>0)
			{
				response.sendRedirect(request.getParameter("forward"));
			  request.getSession().removeAttribute("forward");
			  return null;
			}
		  if (request.getSession().getAttribute("requestURI")!=null)
		    {
					if (request.getParameter("backToReferer")!=null && new Boolean(request.getParameter("backToReferer")))
					{
						response.sendRedirect((String)request.getSession().getAttribute("requestURI"));
						request.getSession().removeAttribute("requestURI");
						return null;
					} else
					{
						request.setAttribute("forward",request.getSession().getAttribute("requestURI"));
						request.getSession().removeAttribute("requestURI");
					}
		    }
			if (request.getParameter("backToReferer")!=null && new Boolean(request.getParameter("backToReferer")) && request.getHeader("Referer")!=null)
				if (!new URL(request.getHeader("Referer")).getPath().equals(request.getRequestURI()))
				{
					response.sendRedirect(request.getHeader("Referer"));
					return null;
				}
		  return mapping.findForward("loginok");
		} catch (Throwable e)
		{
//			user.setPortalid(null);
//			user.setId(null);
			log.error(e.getMessage(),e);
			saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("loginko");
		}
	}
	
/*	protected UserSessionSBean getUserSession(String portalid, String userid, String password) throws Exception
	{
	  return new UserSessionSBean(usermanager.getUserSession(portalid,userid,password));
	}*/
	
	protected Map<String,String> getPortalWarnings(Portal portal) throws RemoteException, FinderException
	{
		Map<String,String> warnings = new HashMap<String,String>();

		if (portal.getHomeurl()==null || portal.getHomeurl().length()<5)
			warnings.put("warning.noHomeURL","system");
//		if (portal.getBgcolor()==null || portal.getTextcolor()==null || portal.getHtextcolor()==null || portal.getImgsurl()==null)
//			warnings.put("warning.noportalcolors","system/graphics.jsp");
		try
		{
			usermanager.getRole(portal.getId(),"user");
		} catch (Throwable e)
		{
			warnings.put("warning.noUserRole","user");
		}
		if (usermanager.getNewUserRoles(portal.getId()).size()==0)
			warnings.put("warning.noNewUserRoles","user");
		return warnings;
	}
	
/*	public ActionForward adminlogin(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		UserActionForm user = (UserActionForm)form;
		try
		{
			UserSBean userdto = usermanager.getUser(user.getPortalid(),user.getUserid(),user.getPassword());
			BeanUtils.copyProperties(user,userdto);
			user.setPkey(userdto.getPkey()); // Por seguridad
			user.setPortal(userdto.getPortal());
		  user.setLoginmessages(getLoginmessages(user.getPortal().getRoles()));
			log.info("ServletContextUtils.validate(): "+user.getUserid()+"@"+user.getPortalid());
			doCookies(user,response);
		} catch (Throwable e)
		{
			user.setPortalid(null);
			user.setId(null);
			user.setPassword(null);
			log.error(e.getMessage(),e);
			ActionErrors errors = new ActionErrors();
			errors.add("error",new ActionMessage(e.getClass().getName(),e.getMessage()));
			saveErrors(request,errors);
			return mapping.findForward("adminloginko");
		}
		return mapping.findForward("adminloginok");
	}*/
	public ActionForward logout(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		//boolean admin = request.getHeader("referer")!=null && request.getHeader("referer").indexOf("admin")>-1;
		try
		{
			UserSessionSBean userSession = getUserSession(request);
			String portalid = userSession.getPortal().getId();
		  String homeurl = userSession.getPortal().getHomeurl();
			if (request.getParameter("keepRememberedSession")==null || !new Boolean(request.getParameter("keepRememberedSession")))
				removeRememberedSession(portalid,response);
//			request.getSession(true).removeAttribute("user");
//			request.getSession(true).removeAttribute("userdata");
			request.getSession().invalidate();
		  logManager.log(portalid,userSession.getUser().getId(),"user","UserUnidentifiedActions","logout",userSession.getUserid(),request.getRemoteAddr());
			if (request.getParameter("forward")!=null) //Deprecated
			  response.sendRedirect(request.getParameter("forward"));
		  if (request.getParameter("redirect")!=null)
		    response.sendRedirect(request.getParameter("redirect"));
			else
				response.sendRedirect(homeurl==null?request.getScheme()+"://"+request.getServerName()+(request.getServerPort()==80?"":":"+request.getServerPort())+request.getContextPath()+"/portal/Actions.do?portalid="+portalid:(homeurl.startsWith("http")?homeurl:"http://"+homeurl));
		  //return mapping.findForward("logoutok");
			//return mapping.findForward((admin?"admin":"")+"logoutok");
			return null;
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
			saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	public ActionForward passwordChangeMailRequestForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		return mapping.findForward("passwordChangeMailRequestForm");
	}
	
	public ActionForward sendPasswordChangeMailRequest(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		try
		{
		  if (!validateRandomText(request.getSession(),request.getParameter("validationText")))
		    throw new IllegalArgumentException("error.InvalidRandomText");
		  UserActionForm user = (UserActionForm)form;
			UserSessionSBean userSession = getUserSession(request);
		  User userdto = usermanager.getUser(userSession.getPortalid(), user.getUserid());
		  InternetAddress useremail = InternetAddress.parse(userdto.getEmail())[0];
		  InternetAddress adminemail = portalmanager.getEmail(userSession.getPortalid());
		  if (adminemail==null)
		    throw new IllegalStateException("error.noAdminEmail");
		  if (useremail==null)
		    throw new IllegalStateException("error.noUserEmail");

			request.setAttribute("authCode", getTodayChangePasswordDigitalSignature(userSession.getPortalid(), user.getUserid()));
		  String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/passwordChangeRequestMail.jsp");
			getMailRelay().send(adminemail.getAddress(), useremail.getAddress(), "Password change request", null, html);
			return mapping.findForward("passwordChangeMailRequestSentOK");
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
		  saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	private String getTodayChangePasswordDigitalSignature(String portalid, String userid)
	{
		SimpleDateFormat todate = new SimpleDateFormat("ddMMyyyy");
		String[] values = new String[4];
		values[0] = portalid;
		values[1] = userid;
		values[2] = todate.format(new Date());
		values[3] = portalid + "qert123";
		return UserManagerBean.getMessageDigest(values);
	}

	public ActionForward sendNewPassword(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		try
		{
		  UserActionForm user = (UserActionForm)form;
		  UserSessionSBean userSession = getUserSession(request);
		  if (!request.getParameter("authCode").equals(getTodayChangePasswordDigitalSignature(userSession.getPortalid(), user.getUserid())))
		    throw new java.security.InvalidKeyException("Keys don'y match");
		  int pass = new Random().nextInt(99999);
		  pass += 4567;
		  usermanager.changeUserPassword(userSession.getPortalid(), user.getUserid(), pass + "");
			User userdto = usermanager.getUser(userSession.getPortalid(), user.getUserid());
			request.setAttribute("password", pass);
			String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/requestedNewPassword.jsp");
			getMailRelay().send(portalmanager.getEmail(userdto.getPortalid()).getAddress(), userdto.getEmail(), "Your new password", null, html);
		  logManager.log(userSession.getPortalid(),userSession.getUser().getId(),"user","UserUnidentifiedActions","sendNewPassword",userSession.getUserid(),request.getRemoteAddr());
		  return mapping.findForward("newPasswordSentOK");
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
		  saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	private String getSignupsignature(String portalid, String userid)
	{
		String[] values = { portalid, userid };
		return UserManagerBean.getMessageDigest(values);
	}

	public ActionForward sendSignupConfirmationRequestMail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		try
		{
		  UserSessionSBean userSession=getUserSession(request);
			if (userSession.isGuest())
				return mapping.findForward("loginform");
		     request.setAttribute("authCode",getSignupsignature(userSession.getPortalid(),userSession.getUser().getUserid()));
		  String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/signupConfirmationRequestMail.jsp");
		  getMailRelay().send(portalmanager.getEmail(userSession.getPortalid()).getAddress(), userSession.getUser().getEmail(), "Signup confirmation request", null, html);
		  return mapping.findForward("signupConfirmationRequestMailSent");
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
		  saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	
	public ActionForward sendUserIdsByEmail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		try
		{
		  UserSessionSBean userSession=getUserSession(request);
		  UserActionForm user = (UserActionForm)form;
			if (!validateRandomText(request.getSession(),request.getParameter("validationText")))
				throw new IllegalArgumentException("error.InvalidRandomText");
			request.setAttribute("usersByEmail",usermanager.getUsersByEmail(user.getEmail()));
		  String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/usersByEmailMail.jsp");
		  getMailRelay().send(portalmanager.getEmail(userSession.getPortalid()).getAddress(), userSession.getUser().getEmail(), "Your userids", null, html);
		  return mapping.findForward("usersByEmailSent");
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
			saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}

	public ActionForward user(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException,ServletException
	{
		try
		{
			UserActionForm userForm = (UserActionForm)form;
			User edituser = userForm.getId() == null ?
				usermanager.getUser(getUserSession(request).getPortalid(),userForm.getUserid()):
				usermanager.getUser(getUserSession(request).getPortalid(),userForm.getId());
//		  edituser.setHasPicture(new java.io.File(getServicedir(edituser.getPortalid(),"user",true),edituser.getPkey()+".jpg").exists());
			request.setAttribute("edituser",edituser);
		} catch (Throwable e)
		{
			log.error(e.getMessage(),e);
			saveErrors(request,getErrorsFromException(e));
			return mapping.findForward("error");
		}
		return mapping.findForward("user");
	}
	public ActionForward signdownForm(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		try
		{
		  UserSessionSBean userSession=getUserSession(request);
			if (!userSession.getPortal().isUserSelfSignup())
				throw new IllegalArgumentException("portal.userSelfSignupDisabled");
			return mapping.findForward("signdownForm");
		} catch (Throwable e)
		{
			log.error(e.getMessage(), e);
			saveErrors(request, getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	public ActionForward signdown(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		try
		{
			UserSessionSBean userSession = getUserSession(request);
		  UserActionForm user = (UserActionForm)form;
			User userDTO = usermanager.getUser(userSession.getPortalid(),user.getUserid());
			for (Role role: userDTO.getRoles())
				if (role.getName().equals("admin"))//FIXME No mola mirar así si el role es admin
					throw new IllegalArgumentException("error.cantSelfSigndownAsYouAreAdminUser");
			if (!userDTO.getPortal().isUserSelfSignup())
				throw new IllegalArgumentException("portal.userSelfSignupDisabled");
			if (!userDTO.checkEncodedPassword(user.getPassword()))
				throw new IllegalArgumentException("error.invalidUseridOrPassword");
			if (!userSession.isGuest())
			{
				request.getSession().invalidate();
				removeRememberedSession(userDTO.getPortalid(),response);
			}
			usermanager.removeUser(userDTO);
			
		  String html = getServletContextUtils().getResourceAsString(userSession.getUser(),request,response,"/user/signdownConfirmation.jsp");
		  getMailRelay().send(portalmanager.getEmail(userSession.getPortalid()).getAddress(), userDTO.getEmail(), "Signdown confirmation", null, html);

		  logManager.log(userSession.getPortalid(),userSession.getUser().getId(),"user","UserUnidentifiedActions","signdown",userSession.getUserid(),request.getRemoteAddr());
			return mapping.findForward("signdown");
		} catch (Throwable e)
		{
			log.error(e.getMessage(), e);
			saveErrors(request, getErrorsFromException(e));
			return mapping.findForward("error");
		}
	}
	public ActionForward picture(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
	  UserSessionSBean userSession = getUserSession(request);
	  byte[] picture = usermanager.getUser(userSession.getPortalid(),((UserActionForm)form).getUserid()).getPicture();
		if (picture!=null)
		{
			response.setContentType("image/jpg");
			write(picture,response);
		}
		return null;
	}
	public ActionForward thumbnail(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
	{
		UserSessionSBean userSession = getUserSession(request);
		byte[] array = usermanager.getUser(userSession.getPortalid(),((UserActionForm)form).getUserid()).getPicture();
	  if (array!=null)
		{
			Image picture = ThumbnailUtils.JPEGtoImage(new ByteArrayInputStream(array));
			BufferedImage bufferedImage = ThumbnailUtils.getScaledimage(picture,new Dimension(80,60));
			ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
			ThumbnailUtils.writeJPG(bufferedImage,byteOutputStream,(float)0.5);
			response.setContentType("image/jpg");
			write(byteOutputStream.toByteArray(),response);
		}
		return null;
	}
}
